package tab;

import org.come.Frame.TabbePaneUI;
import org.come.until.Music;
import org.come.until.Util;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class TabJFrame extends JFrame {

	private static final long serialVersionUID = 3156686807197430608L;
	private static final int BUFFER_SIZE = 8192; // 增大缓冲区
	private static final String ROLE_NAME_PREFIX = "Rolename:";

	JPanel add;
	String jiahao = "＋";
	JPanel addBTC;

	// 使用ConcurrentHashMap提高线程安全性
	public final JTabbedPane jTabbedPane = new JTabbedPane() {
		private static final long serialVersionUID = -7124319121198561699L;

		{
			setUI(new TabbePaneUI() {
				@Override
				protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) {
					int width = super.calculateTabWidth(tabPlacement, tabIndex, metrics);
					if (!games.containsKey(tabIndex) && tabIndex < index)
						return 0;
					return width;
				}
			});
		}
	};

	public static volatile int index = 0;
	public static volatile int shouId = 0;
	// 使用ConcurrentHashMap提高线程安全性
	public static final Map<Integer, Process> games = new ConcurrentHashMap<>();
	public static int tabCount = 0;
	public boolean start = false;

	public TabJFrame() {
		setResizable(false);
		Toolkit tool = this.getToolkit();
		Image myimage = tool.getImage("img/icon/ico.png");
		this.setIconImage(myimage);
		add(jTabbedPane);
		jTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		add = createContent(-1);
		addBTC = new ButtonTabComponent(jTabbedPane, false);
		jTabbedPane.add(jiahao, add);
		jTabbedPane.setTabComponentAt(0, addBTC);
		int id = addGame();
		showGame(id);
		this.setPreferredSize(new Dimension(645, 500));
		this.setTitle(Main.title);
		this.pack();
		this.setLocationRelativeTo(null);
		setLocation(0, 0);

		// 添加窗口关闭监听器，确保资源清理
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent windowEvent) {
				dispose();
			}
		});
	}

	public int addGame() {
		ProcessBuilder processBuilder = getProcess(index);
		Process process;
		try {
			process = processBuilder.start();
			final Process finalProcess = process;
			final int id = index;

			// 使用BufferedReader优化输入流处理
			Thread readerThread = new Thread(() -> {
				try (BufferedReader reader = new BufferedReader(
						new InputStreamReader(finalProcess.getInputStream(), StandardCharsets.UTF_8), BUFFER_SIZE)) {
					String line;
					while ((line = reader.readLine()) != null) {
						if (line.startsWith(ROLE_NAME_PREFIX)) {
							String roleName = line.substring(ROLE_NAME_PREFIX.length());
							// 使用SwingUtilities.invokeLater确保线程安全
							javax.swing.SwingUtilities.invokeLater(() -> {
								try {
									jTabbedPane.setTitleAt(id, roleName);
								} catch (Exception e) {
									// 忽略异常，避免因tab关闭导致的问题
								}
							});
							break; // 找到角色名后可以退出循环
						}
					}
				} catch (Exception e) {
					// 记录异常但不打印堆栈，避免影响性能
				}
			}, "GameOutputReader-" + id);
			readerThread.setDaemon(true); // 设置为守护线程
			readerThread.start();

		} catch (IOException e) {
			return -1;
		}

		jTabbedPane.remove(index);
		games.put(index, process);
		JPanel tab = createContent(index);
		ButtonTabComponent btc = new ButtonTabComponent(jTabbedPane, true);
		jTabbedPane.add(tab, Main.title, index);
		jTabbedPane.add(add, "+", index + 1);
		jTabbedPane.setTabComponentAt(index, btc);
		jTabbedPane.setTabComponentAt(index + 1, addBTC);
		return index++;
	}

	public void removeGame(int id) {
		// 清理进程资源
		Process process = games.remove(id);
		if (process != null && process.isAlive()) {
			process.destroyForcibly();
		}
		jTabbedPane.setTabComponentAt(id, new JLabel());
	}

	public void showGame(int id) {
		tab.Main.lastX = -1;
		tab.Main.lastY = -1;
		shouId = id;
	}

	public JTabbedPane getjTabbedPane() {
		return jTabbedPane;
	}

	// 修复缺失的方法
	public Map<Integer, Process> getGames() {
		return games;
	}

	public int getShouId() {
		return shouId;
	}

	public ProcessBuilder getProcess(int id) {
		List<String> res = new ArrayList<>(32); // 预设容量避免频繁扩容
		if (tab.Main.debug) {
			// 优化Java路径获取
			String javaPath = findJavaExecutable();
			res.add(javaPath);

			// 添加内存优化参数 - 优化多开内存使用
			res.add("-Xms32m");              // 减少初始堆内存
			res.add("-Xmx256m");             // 减少最大堆内存
			res.add("-XX:NewSize=16m");      // 减少年轻代内存
			res.add("-XX:MaxNewSize=64m");   // 减少最大年轻代内存
			res.add("-XX:MetaspaceSize=16m"); // 减少元空间初始大小
			res.add("-XX:MaxMetaspaceSize=32m"); // 减少元空间最大大小
			res.add("-XX:+UseSerialGC");     // 使用串行垃圾收集器，适用于小内存应用
			res.add("-XX:ReservedCodeCacheSize=16m"); // 减少代码缓存大小
			res.add("-Xss256k");             // 减少线程栈大小
			res.add("-Dfile.encoding=UTF-8");
			res.add("-Dsun.zip.disableMemoryMapping=true");

			// Netty优化参数
			res.add("-Dio.netty.eventLoopThreads=2");  // 减少Netty线程数
			res.add("-Dio.netty.maxDirectMemory=32m"); // 减少直接内存

			res.add("-classpath");
			// 优化类路径构建
			res.add(buildClassPath());
			res.add("com.mains.Main");
			res.add("-index");
			res.add(String.valueOf(id));
			res.add("-Dfile.encoding=UTF-8");
		} else {
			res.add("game.exe");
			res.add("-index");
			res.add(String.valueOf(id));
		}

		ProcessBuilder processBuilder = new ProcessBuilder(res);
		processBuilder.directory(new File(tab.Main.dir));
		return processBuilder;
	}

	/**
	 * 查找Java可执行文件路径
	 */
	private String findJavaExecutable() {
		try {
			String javaHome = System.getProperty("java.home");
			if (javaHome != null) {
				File javaExe = new File(javaHome, "bin/java.exe");
				if (javaExe.exists()) {
					return "\"" + javaExe.getAbsolutePath() + "\"";
				}
			}
		} catch (Exception e) {
			// 忽略异常
		}

		// 回退方案
		File relativeJavaExe = new File("jre/bin/java.exe");
		if (relativeJavaExe.exists()) {
			return "\"" + relativeJavaExe.getAbsolutePath() + "\"";
		}

		return "java";
	}

	/**
	 * 优化类路径构建
	 */
	private String buildClassPath() {
		StringBuilder classpath = new StringBuilder(1024);
		classpath.append("\"").append(tab.Main.dir).append("\\bin;");

		// 使用通配符简化类路径
		classpath.append(tab.Main.dir).append("\\jre\\lib\\*;");
		classpath.append(tab.Main.dir).append("\\jre\\lib\\ext\\*;");
		classpath.append(tab.Main.dir).append("\\jre\\lib\\security\\policy\\limited\\*;");
		classpath.append(tab.Main.dir).append("\\jre\\lib\\security\\policy\\unlimited\\*;");
		classpath.append(tab.Main.dir).append("\\bin\\libs\\*;");
		classpath.append("\"");

		return classpath.toString();
	}

	/**
	 * 清理所有子进程
	 */
	private void cleanupProcesses() {
		games.forEach((id, process) -> {
			try {
				if (process != null && process.isAlive()) {
					process.destroyForcibly();
				}
			} catch (Exception e) {
				// 忽略异常
			}
		});
		games.clear();
	}

	/**
	 * 窗口关闭时清理资源
	 */
	@Override
	public void dispose() {
		// 清理所有子进程
		cleanupProcesses();
		super.dispose();
	}

	private JPanel createContent(int id) {
		JPanel panel = new JPanel() {
			private static final long serialVersionUID = -8826374588279483244L;

			@Override
			public void setVisible(boolean aFlag) {
				if (aFlag == isVisible())
					return;
				super.setVisible(aFlag);
				if (aFlag) {
					if (id >= 0) {
						if (TabJFrame.shouId != id)
							showGame(id);
					} else {
						if (index > 0 && !tab.Main.addIng) {
							int ii = TabJFrame.shouId;
							tab.Main.addIng = true;
							addGame();
							jTabbedPane.setSelectedIndex(ii);
							Main.addIng = false;
						}
					}
				}
			}
		};
		panel.setBackground(Color.BLACK);
		int random = Util.random.nextInt(7);
		JLabel label = new JLabel(new ImageIcon("inkImg/background/new_img/bg/" + random + "_gameLoading_bg.png"));
		panel.add(label);
		return panel;
	}
}
